package com.cium.aqie.highOrderFunction

import java.io.OutputStream
import java.nio.charset.Charset

/**
 * @Function: 柯力化
 * @Author: aqie
 * @Date: 2019/9/2 11:55
 */
fun hello(x:String, y:Int,z:Double):Boolean{
    return true
}

// fun currentHello(x:String):(y:Int)->(z:Double)->Boolean

fun log(tag: String, target: OutputStream, message: Any?){
    target.write("[$tag] $message\n".toByteArray())
}

// 柯力化
/*fun log(tag: String)
    = fun(target: OutputStream)
    = fun(message: Any?)
    = target.write("[$tag] $message\n".toByteArray())*/

/**
 * 将普通函数变为柯力化版本
 */
fun <P1, P2, P3, R> Function3<P1, P2, P3, R>.curried()
        = fun(p1: P1) = fun(p2: P2) = fun(p3: P3) = this(p1, p2, p3)

/**
 * 固定参数 的偏函数
 */
fun <P1, P2, R> Function2<P1, P2, R>.partial2(p2: P2) = fun(p1: P1) = this(p1, p2)
fun <P1, P2, R> Function2<P1, P2, R>.partial1(p1: P1) = fun(p2: P2) = this(p1, p2)

val makeString = fun(byteArray: ByteArray, charset: Charset): String{
    return String(byteArray, charset)
}

// 第二个参数绑定的 偏函数
val makeStringFromGbkBytes = makeString.partial2(charset("GBK"))

fun main() {
    log("aqie", System.out, "Hello World")
    // log("cium")(System.out)("hello World")
    ::log.curried()("benny")(System.out)("HelloWorld Again.")
    // 偏函数
    val consoleLogWithTag = (::log.curried())("啊切")(System.out)
    consoleLogWithTag("HelloAgain Again.")

    val bytes = "我是中国人".toByteArray(charset("GBK"))
    val stringFromGBK = makeStringFromGbkBytes(bytes)
    println(stringFromGBK)
}